#include "common.hpp"

void usage(string name){
	cout << "Usage: " << endl;
	cout << "       " << "-d: video device path, necessary" << endl;
	cout << "       " << "-w: width" << endl;
	cout << "       " << "-h: height" << endl;
	cout << "       " << "-f: format" << endl;
	cout << "       " << "-i: input file path" << endl;
	cout << "       " << "-F: fps" << endl;
	cout << "       " << "-D: Enable debug" << endl;
	cout << endl;
	cout << "Examples:" << endl;
	cout << "       " << name << " -d /dev/video11 -i /data/test.nv12 -F 30 -w 1920 -h 1080 -f NV12" << endl;
	cout << endl;
	cout << "Format Suport List:" << endl;
	cout << "       " << " NV12" << endl;
	cout << "       " << " NV21" << endl;
	cout << "       " << " RGB3" << endl;
	cout << "       " << " BGR3" << endl;
}


int main(int argc,char ** argv){
	string _FMT;
	string RGA_FMT;
	string DEVICE;
	string INPUT_FILE;
	int flag = false;

	if(argc == 1){
		usage(argv[0]);
		return -1;
	}

	int o = 0;
	while(( o = getopt(argc,argv,"d:w:h:f:Di:F:")) != -1){
		switch(o){
			case 'F':
				FPS = atoi(optarg);
				break;
			case 'i':
				INPUT_FILE = optarg;
				break;
			case 'f':
				_FMT = optarg;
				break;
			case 'w':
				WIDTH = atoi(optarg);
				break;
			case 'h':
				HEIGHT = atoi(optarg);
				break;
			case 'd':
				DEVICE = optarg;
				break;
			case 'D':
				MAN_DEBUG_OUT = true;
				break;
			default:
				usage(argv[0]);
				return -1;
		}
	}

	for(int i = 0; i < sizeof(man_pixfmt) / sizeof(man_pixfmt[0]); i++){
		if(!_FMT.compare(man_pixfmt[i].name)){
			FMT = man_pixfmt[i].rga_fmt;
			RGA_FMT = man_pixfmt[i].rga_fmt_name;
			flag = true;
			break;	
		}
	}

	if(flag == false){
		cout << "Not support FMT: " << _FMT << endl;
		return -1;
	}

	
	cout << "OPT LIST" << endl;
	cout << "DEVICE: " << DEVICE << endl;
	cout << "WIDTH: " << WIDTH << endl;
	cout << "HEIGHT: " << HEIGHT << endl;
	cout << "_FMT: " << _FMT << endl;
	cout << "FMT(RGA): " << RGA_FMT << endl;
	cout << "FPS: " << FPS << endl;
	cout << "INPUT_FILE: " << INPUT_FILE << endl;
	cout << "DEBUG: " << MAN_DEBUG_OUT << endl;
	
	void * addr = NULL;
	ManGetTime time;
	int read_size = 0;
	int fps_time = 1000 / FPS;
	int size = WIDTH * HEIGHT * 3 / 2;
	
	int delay = 0;
	ManV4L2 v4l2(DEVICE,MAN_OUTPUT);
	v4l2.init();
	v4l2.setFmt(_FMT,WIDTH,HEIGHT);
	v4l2.streamOn();

	FILE * yuv_file = fopen (INPUT_FILE.c_str(),"rb");
	if (yuv_file == NULL) {
		cout << "can not open yuv file" << endl;
	}

	while(1){	
		time.SetStart();
		addr = v4l2.getFrame(-1);
		int read_size = fread(addr, 1, size, yuv_file);
		if(read_size != size) {
			fseek( yuv_file, 0, SEEK_SET );
		}
		delay = time.GetEndToStart();
		if(fps_time > delay)
			usleep(1000 * (fps_time - delay));

		v4l2.putFrame(addr);
		delay = time.GetEndToStart();
		if(MAN_DEBUG_OUT == true)
			cout << "[OUT] Delay time: " << delay << endl;
	}
	
	fclose(yuv_file);
	v4l2.streamOff();
	return 0;

}
